//package test.buildpatch;
//
//import org.apache.commons.cli.*;
//import test.common.StringUtils;
//
//import java.io.*;
//import java.nio.ByteBuffer;
//import java.nio.channels.FileChannel;
//import java.sql.*;
//import java.util.*;
//import java.util.stream.Collectors;
//
///**
// * 一个简单的临时的补丁打包工具
// */
//public class PatchMaker {
//    private Map<String, Map<String, String>> configMap;
//    private Map<String, String> config;
//
//    private String PROJECT_ROOT;
//    /**
//     * 部署在服务器上面的地址
//     */
//    private String PROJECT_ARTIFACT_DIR;
//    /**
//     * class文件夹名称
//     */
//    private String CLASSES_DIR = "WEB-INF/classes";
//    /**
//     * class文件夹的真实路径
//     */
//    private String PROJECT_ARTIFACT_CLASSES_DIR;
//    /**
//     * 补丁输出文件夹
//     */
//    private String PATCH_OUT_DIR;
//    /**
//     * 改动补丁文件夹列表(可以直接使用idea格式)
//     */
//    private String INPUT_FILE;
//    /**
//     * 源码目录
//     */
//    private String SOURCE_DIR = "源码";
//    /**
//     * java源码目录
//     */
//    private String JAVA_SOURCE_DIR = "src";
//    /**
//     * 数据库脚本目录
//     */
//    private String OUTPUT_DATABASE_SCRIPT_DIR = "数据库脚本";
//    /**
//     * 网页根目录
//     */
//    private String WEB_ROOT = "WebRoot";
//    /**
//     * 过滤关键字列表
//     */
//    private List<String> EXCLUDE_WORDS = new ArrayList<>();
//
//    /**
//     * 输出程序文件夹
//     */
//    private String OUTPUT_WEBAPP_DIR = "程序";
//
//    private List<String> modifyFiles = new ArrayList<>();
//    /**
//     * 输出的补丁文件夹名称（可选）
//     */
//    private String outPatchDirName;
//
//    private PatchMaker() {
//        configMap = new HashMap<>();
//        //广西内保
//        Map<String, String> config = new HashMap<>();
//        config.put("PROJECT_ROOT", "/home/firefoxmmx2/Work/加油站散装油系统");
//        config.put("PROJECT_ARTIFACT_DIR", config.get("PROJECT_ROOT") + "/out/artifacts/_war_exploded");
//        config.put("CLASSES_DIR", "/WEB-INF/classes");
//        config.put("PROJECT_ARTIFACT_CLASSES_DIR", config.get("PROJECT_ARTIFACT_DIR") + config.get("CLASSES_DIR"));
//        config.put("PATCH_OUT_DIR", "/home/firefoxmmx2/Work/加油站散装油系统/补丁/内保单位综合系统v4.1.4-v4.1.6.1");
//        config.put("INPUT_FILE", "/home/firefoxmmx2/加油站散装油文件更新列表.txt");
//        config.put("SOURCE_DIR", "源码");
//        config.put("JAVA_SOURCE_DIR", "src");
//        config.put("OUTPUT_DATABASE_SCRIPT_DIR", OUTPUT_DATABASE_SCRIPT_DIR);
//        config.put("OUTPUT_WEBAPP_DIR", OUTPUT_WEBAPP_DIR);
//        config.put("WEB_ROOT", "WebRoot");
//        configMap.put("gxnbdw", config);
//
//
//        //海南社采
//        config = new HashMap<>();
//        config.put("PROJECT_ROOT", "/home/firefoxmmx2/Work/海南社采平台");
//        config.put("PROJECT_ARTIFACT_DIR", config.get("PROJECT_ROOT") + "/out/artifacts/hnscpt_war_exploded");
//        config.put("CLASSES_DIR", "/WEB-INF/classes");
//        config.put("PROJECT_ARTIFACT_CLASSES_DIR", config.get("PROJECT_ARTIFACT_DIR") + config.get("CLASSES_DIR"));
//        config.put("PATCH_OUT_DIR", "/home/firefoxmmx2/Work/海南社采平台/补丁/海南社采平台v1.7-v1.8补丁");
//        config.put("INPUT_FILE", "/home/firefoxmmx2/海南社采更新列表.txt");
//        config.put("SOURCE_DIR", "hnscpt");
//        config.put("JAVA_SOURCE_DIR", "src");
//        config.put("OUTPUT_DATABASE_SCRIPT_DIR", OUTPUT_DATABASE_SCRIPT_DIR);
//        config.put("WEB_ROOT", "WebRoot");
//        config.put("OUTPUT_WEBAPP_DIR", OUTPUT_WEBAPP_DIR);
//
//        configMap.put("hnscpt", config);
//
//        //广西内保企业接口
//        config = new HashMap<>();
//        config.put("PROJECT_ROOT", "/home/firefoxmmx2/Work/加油站散装油系统企业接口");
//        config.put("PROJECT_ARTIFACT_DIR", config.get("PROJECT_ROOT") + "/out/artifacts/_Web_exploded");
//        config.put("CLASSES_DIR", "/WEB-INF/classes");
//        config.put("PROJECT_ARTIFACT_CLASSES_DIR", config.get("PROJECT_ARTIFACT_DIR") + config.get("CLASSES_DIR"));
//        config.put("PATCH_OUT_DIR", "/home/firefoxmmx2/Work/加油站散装油系统企业接口/补丁/加油站散装油系统企业接口v1.5-v1.6");
//        config.put("INPUT_FILE", "/home/firefoxmmx2/加油站散装油系统企业接口更新列表.txt");
//        config.put("SOURCE_DIR", "源码");
//        config.put("JAVA_SOURCE_DIR", "src");
//        config.put("OUTPUT_DATABASE_SCRIPT_DIR", OUTPUT_DATABASE_SCRIPT_DIR);
//        config.put("WEB_ROOT", "WebRoot");
//        config.put("OUTPUT_WEBAPP_DIR", OUTPUT_WEBAPP_DIR);
//
//        configMap.put("gxnbdwzshjk", config);
//    }
//
//    //初始化
//    private PatchMaker(String configName) {
//        this();
//        config = configMap.get(configName);
//        //默认添加补丁为排除关键字
//        EXCLUDE_WORDS.add("补丁");
//
//        PROJECT_ROOT = config.get("PROJECT_ROOT");
//        PROJECT_ARTIFACT_DIR = config.get("PROJECT_ARTIFACT_DIR");
//        PROJECT_ARTIFACT_CLASSES_DIR = config.get("PROJECT_ARTIFACT_CLASSES_DIR");
//        PATCH_OUT_DIR = config.get("PATCH_OUT_DIR");
//        INPUT_FILE = config.get("INPUT_FILE");
//        SOURCE_DIR = config.get("SOURCE_DIR");
//        JAVA_SOURCE_DIR = config.get("JAVA_SOURCE_DIR");
//        OUTPUT_DATABASE_SCRIPT_DIR = config.get("OUTPUT_DATABASE_SCRIPT_DIR");
//        CLASSES_DIR = config.get("CLASSES_DIR");
//        WEB_ROOT = config.get("WEB_ROOT");
//        OUTPUT_WEBAPP_DIR = config.get("OUTPUT_WEBAPP_DIR");
//    }
//
//    /**
//     * 打包补丁
//     */
//    private void buildPatch() throws IOException {
//        File patchOutDir = new File(PATCH_OUT_DIR);
//        if (!patchOutDir.exists()) {
//            patchOutDir.mkdirs();
//        }
//        if(StringUtils.isNotEmpty(outPatchDirName)){
//            patchOutDir = new File(patchOutDir.getPath()+File.separator+outPatchDirName);
//            if (patchOutDir.exists()) {
//                patchOutDir.mkdirs();
//            }
//        }
//        if (StringUtils.isNotEmpty(INPUT_FILE)) {
//            File inputFile = new File(INPUT_FILE);
//            BufferedReader bufferedReader = new BufferedReader(new FileReader(inputFile));
//            String filepath;
//            while ((filepath = bufferedReader.readLine()) != null) {
//                if (StringUtils.isNotEmpty(filepath))
//                    modifyFiles.add(filepath);
//            }
//        }
//
//        if (modifyFiles.isEmpty())
//            throw new RuntimeException("已经修改的版本文件列表没有数据");
//
//        modifyFiles.forEach(filepath -> {
//            List<String> fromPaths = new ArrayList<>();
//            List<String> toPaths = new ArrayList<>();
//            File file = new File(filepath);
//            boolean hasExcludeWords = false;
//            for (String excludeWord : EXCLUDE_WORDS) {
//                if (filepath.contains(excludeWord)) {
//                    hasExcludeWords = true;
//                    break;
//                }
//            }
//            if (file.getName().contains(".") && !hasExcludeWords)
//                if (filepath.contains(SOURCE_DIR + File.separator) && filepath.contains(JAVA_SOURCE_DIR + File.separator)) {        //源码
//                    String path = filepath.substring(filepath.indexOf(JAVA_SOURCE_DIR + File.separator) + (JAVA_SOURCE_DIR + File.separator).length())
//                            .replaceAll("\\.java", ".class");
//                    fromPaths.add(PROJECT_ARTIFACT_CLASSES_DIR + File.separator + path);
//                    toPaths.add(PATCH_OUT_DIR + File.separator + OUTPUT_WEBAPP_DIR + File.separator + CLASSES_DIR + File.separator + path);
//
//                    if (path.contains(".class")) {   //支持内部类
//                        final File fromPathFile0 = new File(PROJECT_ARTIFACT_CLASSES_DIR + File.separator + path);
//                        File[] subclassFiles = fromPathFile0.getParentFile().listFiles((dir, name) -> name.contains(fromPathFile0.getName().split(".class")[0] + "$"));
//                        if (subclassFiles != null)
//                            for (File subclassFile : subclassFiles) {
//                                String subclass = subclassFile.getPath();
//                                fromPaths.add(subclass);
//                                toPaths.add(PATCH_OUT_DIR + File.separator + OUTPUT_WEBAPP_DIR +File.separator + CLASSES_DIR + File.separator + subclass.split(PROJECT_ARTIFACT_CLASSES_DIR + File.separator)[1]);
//                            }
//                    }
//
//                } else if (filepath.contains(SOURCE_DIR + File.separator) && filepath.contains(WEB_ROOT + File.separator)) { //WEB根目录
//                    String path = filepath.substring(filepath.indexOf(WEB_ROOT + File.separator) + (WEB_ROOT + File.separator).length());
//                    fromPaths.add(PROJECT_ARTIFACT_DIR + File.separator + path);
//                    toPaths.add(PATCH_OUT_DIR + File.separator + OUTPUT_WEBAPP_DIR + File.separator + path);
//                } else if (filepath.contains(OUTPUT_DATABASE_SCRIPT_DIR + File.separator)) {   //数据库脚本
//                    String path = filepath.substring(filepath.indexOf(OUTPUT_DATABASE_SCRIPT_DIR + File.separator)
//                            + (OUTPUT_DATABASE_SCRIPT_DIR + File.separator).length());
//                    fromPaths.add(PROJECT_ROOT + File.separator + OUTPUT_DATABASE_SCRIPT_DIR + File.separator + path);
//                    toPaths.add(PATCH_OUT_DIR + File.separator + OUTPUT_DATABASE_SCRIPT_DIR + File.separator + path);
//                }
//
//            for (int i = 0; i < fromPaths.size(); i++) {
//                String fromPath = fromPaths.get(i);
//                String toPath = toPaths.get(i);
//                try {
//                    writeFile(fromPath, toPath);
//                } catch (IOException e) {
//                    e.printStackTrace();
//                }
//            }
//
//        });
//    }
//
//    private void writeFile(String fromPath, String toPath) throws IOException {
//        if (StringUtils.isNotEmpty(fromPath) && StringUtils.isNotEmpty(toPath)) {
//            File patchFilePath = new File(toPath);
//            if (!patchFilePath.getParentFile().exists())
//                patchFilePath.getParentFile().mkdirs();
//            File fromFile = new File(fromPath);
//            if (!fromFile.exists()) {
//                return;
//            }
//            FileInputStream in = new FileInputStream(fromFile);
//            FileOutputStream out = new FileOutputStream(patchFilePath);
//            FileChannel inChannel = in.getChannel();
//            FileChannel outChannel = out.getChannel();
//            ByteBuffer buffer = ByteBuffer.allocate(1024 * 2);
//            while (inChannel.read(buffer) > 0) {
//                buffer.flip();
//                outChannel.write(buffer);
//                buffer.clear();
//            }
//
//            outChannel.close();
//            inChannel.close();
//        }
//    }
//
//    public static PatchMaker parseCommmandLine(String[] args) throws Exception {
//        Option help = new Option("h", "显示这个帮助信息");
//        Option projectRootOption = Option.builder("p")
//                .argName("dir")
//                .hasArg()
//                .desc("包含版本库信息的根目录")
//                .longOpt("projectRoot")
//                .required()
//                .build();
//
//        Option projectArtifactDirOpiton = Option.builder("P")
//                .argName("dir")
//                .hasArg()
//                .desc("编译完成以后发布的目录")
//                .longOpt("projectArtifactDir")
//                .build();
//        Option outClassPathOnlyOption = Option.builder("c")
//                .hasArg()
//                .desc("目标class文件夹名称")
//                .longOpt("outClassPathOnly")
//                .build();
//        Option projectArtifactClassPathOption = Option.builder("C")
//                .argName("dir")
//                .hasArg()
//                .desc("编译完成后发布的class文件路径")
//                .longOpt("projectArtifactClassPath")
//
//                .build();
//        Option oldVersionOption = Option.builder("f")
//                .argName("oldversion")
//                .hasArg()
//                .desc("旧版本号")
//                .longOpt("oldVersion")
//                .required()
//                .build();
//        Option newVersionOption = Option.builder("t")
//                .argName("newversion")
//                .hasArg()
//                .desc("新版本号")
//                .longOpt("newVersion")
//                .required()
//                .build();
//        Option vcsTypeOption = Option.builder("T")
//                .argName("vcstype")
//                .desc("版本管理类型")
//                .longOpt("vcsType")
//                .build();
//
//        Options opts = new Options();
//        opts.addOption(help);
//        opts.addOption(projectRootOption);
//        opts.addOption(projectArtifactDirOpiton);
//        opts.addOption(outClassPathOnlyOption);
//        opts.addOption(projectArtifactClassPathOption);
//        opts.addOption(oldVersionOption);
//        opts.addOption(newVersionOption);
//        opts.addOption(vcsTypeOption);
//
//        opts.addOption("o", "outPatchPath", true, "补丁输出路径");
//        opts.addOption("i", "inputFile", true, "有改动文件列表的问题");
//        opts.addOption("s", "sourceDir", true, "源码文件夹名称");
//        opts.addOption("j", "javaSourceDir", true, "java程序源码文件夹名称例如src之类的");
//        opts.addOption("S", "databaseScriptDir", true, "脚本文件夹名称，程序通过这个名称来确定该文件类型");
//        opts.addOption("w", "webRootDir", true, "设置web源程序根文件夹，默认 WebRoot");
//        opts.addOption("e", "excludeWords", true, "设置过滤的关键字，包含被过滤的关键字的文件将不会出现在补丁里面");
//        opts.addOption("W", "webappDirName", true, "设置程序输出文件夹，默认叫程序");
//        opts.addOption("O", "outPatchDirName", true, "设置补丁输出文件夹名称，设置参数会接在补丁输出路径的后面");
//
//        DefaultParser defaultParser = new DefaultParser();
//        CommandLine cli = defaultParser.parse(opts, args);
//
//        if (cli.getOptions().length == 0 || cli.hasOption("h")) {
//            HelpFormatter helpFormatter = new HelpFormatter();
//            helpFormatter.printHelp("Opitons", opts);
//            System.exit(0);
//        }
//
//        PatchMaker maker = new PatchMaker();
//        maker.PROJECT_ROOT = cli.getOptionValue("p");
//        maker.PROJECT_ARTIFACT_DIR = cli.getOptionValue("P", maker.PROJECT_ROOT + File.separator + "out" + File.separator + "artifacts" + File.separator + "web");
//        maker.CLASSES_DIR = cli.getOptionValue("c", maker.CLASSES_DIR);
//        maker.PROJECT_ARTIFACT_CLASSES_DIR = cli.getOptionValue("C", maker.PROJECT_ARTIFACT_DIR + File.separator + maker.CLASSES_DIR);
//        maker.PATCH_OUT_DIR = cli.getOptionValue("o");
//        maker.INPUT_FILE = cli.getOptionValue("i");
//        maker.SOURCE_DIR = cli.getOptionValue("s", maker.SOURCE_DIR);
//        maker.JAVA_SOURCE_DIR = cli.getOptionValue("j", maker.JAVA_SOURCE_DIR);
//        maker.OUTPUT_DATABASE_SCRIPT_DIR = cli.getOptionValue("S", maker.OUTPUT_DATABASE_SCRIPT_DIR);
//        maker.WEB_ROOT = cli.getOptionValue("w", maker.WEB_ROOT);
//        String excludeWordS = cli.getOptionValue("e", "补丁");
//        maker.EXCLUDE_WORDS = Arrays.stream(excludeWordS.split(",")).collect(Collectors.toList());
//
//        maker.OUTPUT_WEBAPP_DIR = cli.getOptionValue("W", maker.OUTPUT_WEBAPP_DIR);
//        maker.outPatchDirName = cli.getOptionValue("O");
//
//        String oldVersion = cli.getOptionValue("f");
//        String newVersion = cli.getOptionValue("t");
//        String vcsType = cli.getOptionValue("T", "svn");
//
//        PatchMaker.VCSManager vcsManager = maker.new VCSManager(vcsType);
//        maker.modifyFiles = vcsManager.getAction().diff(oldVersion, newVersion);
//        if (vcsManager.getVcsHelperClosable() != null) {
//            vcsManager.getVcsHelperClosable().close();
//        }
//
//        return maker;
//    }
//
//    class VCSManager {
//        /**
//         * 版本管理名称
//         */
//        private String vcsName;
//        /**
//         * 版本管理操作
//         */
//        private VCSAction action;
//        private VCSHelperClosable vcsHelperClosable;
//        private String vcsPath;
//
//        public VCSManager(String vcsName) throws SQLException, ClassNotFoundException {
//            this.vcsName = vcsName;
//
//            if ("svn".equals(this.vcsName)) {
//                this.vcsPath = PROJECT_ROOT + "/.svn/wc.db";
//
//                SVNConnector svn = new SVNConnector(this.vcsPath);
//                action = svn;
//                vcsHelperClosable = svn;
//            }
//        }
//
//        public VCSAction getAction() {
//            return action;
//        }
//
//        public VCSHelperClosable getVcsHelperClosable() {
//            return vcsHelperClosable;
//        }
//    }
//
//    class SVNConnector implements VCSAction, VCSHelperClosable {
//
//        private String svnlibPath;
//        private Connection connection;
//
//        public SVNConnector(String svnlibPath) throws ClassNotFoundException, SQLException {
//            this.svnlibPath = svnlibPath;
//
//            Class.forName("org.sqlite.JDBC");
//            connection = DriverManager.getConnection("jdbc:sqlite:" + this.svnlibPath);
//            connection.setAutoCommit(false);
//        }
//
//        @Override
//        public List<String> diff(String oldVersion, String newVersion) throws SQLException {
//            if (StringUtils.isEmpty(oldVersion))
//                throw new RuntimeException("旧版本号为空");
//            if (StringUtils.isEmpty(newVersion))
//                throw new RuntimeException("新版本号为空");
//            List<String> files = new ArrayList<>();
//            try {
//                PreparedStatement statement = connection.prepareStatement("SELECT repos_path FROM NODES " +
//                        "WHERE changed_revision > ? and changed_revision <= ? and kind='file'");
//                statement.setString(1, oldVersion);
//                statement.setString(2, newVersion);
//                ResultSet resultSet = statement.executeQuery();
//
//                while (resultSet.next()) {
//                    files.add(resultSet.getString(1));
//                }
//            } catch (SQLException e) {
//                System.out.println("比较语句执行出错开始回滚.");
//                e.printStackTrace();
//                connection.rollback();
//            }
//            return files;
//        }
//
//        public void close() throws SQLException {
//            if (connection != null && !connection.isClosed())
//                connection.close();
//        }
//    }
//
//    @FunctionalInterface
//    interface VCSAction {
//        List<String> diff(String oldVersion, String newVersion) throws SQLException;
//    }
//
//    @FunctionalInterface
//    interface VCSHelperClosable {
//        void close() throws Exception;
//    }
//
//    public static void main(String[] args) throws Exception {
////        PatchMaker pm = new PatchMaker("gxnbdw");
////        pm.buildPatch();
//
//        PatchMaker patchMaker = PatchMaker.parseCommmandLine(args);
//        patchMaker.buildPatch();
//    }
//}
